home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Speccy ClassiX 1998
/
Speccy ClassiX 98.iso
/
amiga_system
/
the_aminet
/
dev
/
gcc
/
ixemulsrc.lha
/
ixemul-41.4
/
library
/
mathsup.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-05-20
|
10KB
|
510 lines
/*
* This file is part of ixemul.library for the Amiga.
* Copyright (C) 1991, 1992 Markus M. Wild
* Portions Copyright (C) 1994 Rafael W. Luebbert
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id: mathsup.c,v 1.6 1994/06/25 12:15:02 rluebbert Exp $
*
* $Log: mathsup.c,v $
* Revision 1.6 1994/06/25 12:15:02 rluebbert
* removed errno from pow. Probably not a good idea,
* but I'm tired of patching stuff right now.
*
* Revision 1.5 1994/06/25 12:05:50 rluebbert
* bugfix
*
* Revision 1.4 1994/06/25 11:53:41 rluebbert
* Put in 68881 pow and moved Commodore's to ifndef __HAVE_68881
*
* Revision 1.3 1994/06/19 15:14:01 rluebbert
* *** empty log message ***
*
*
*/
extern struct MathIeeeDoubTransBase * MathIeeeDoubTransBase;
extern struct MathIeeeDoubBasBase * MathIeeeDoubBasBase;
double sincos (double* pf2, double parm)
{
register double res __asm("d0");
register void *a6 __asm ("a6");
register double* a0 __asm("a0");
register double d0 __asm("d0");
a6 = MathIeeeDoubTransBase;
a0 = pf2;
d0 = parm;
__asm volatile ("
jsr a6@(-0x36)"
: "=r" (res)
: "r" (a6), "r" (a0), "r" (d0)
: "d0", "d1", "a0", "a1");
return res;
}
#ifndef __HAVE_68881
/* GRRRR Commodore does it the other way round... */
double const pow (double arg, double exp)
{
register double res __asm("d0");
register void *a6 __asm ("a6");
register double d2 __asm("d2");
register double d3 __asm("d0");
a6 = MathIeeeDoubTransBase;
d2 = exp; /* invert arguments here, so exp really is arg and vice versa */
d3 = arg;
__asm volatile ("
jsr a6@(-0x5a)"
: "=r" (res)
: "r" (a6), "r" (d2), "r" (d3)
: "d0", "d1", "a0", "a1", "d2", "d3");
return res;
}
double const atan (double parm)
{
register double res __asm("d0");
register void *a6 __asm ("a6");
register double d0 __asm("d0");
a6 = MathIeeeDoubTransBase;
d0 = parm;
__asm volatile ("
jsr a6@(-0x1e)"
: "=r" (res)
: "r" (a6), "r" (d0)
: "d0", "d1", "a0", "a1");
return res;
}
double const sin (double parm)
{
register double res __asm("d0");
register void *a6 __asm ("a6");
register double d0 __asm("d0");
a6 = MathIeeeDoubTransBase;
d0 = parm;
__asm volatile ("
jsr a6@(-0x24)"
: "=r" (res)
: "r" (a6), "r" (d0)
: "d0", "d1", "a0", "a1");
return res;
}
double const cos (double parm)
{
register double res __asm("d0");
register void *a6 __asm ("a6");
register double d0 __asm("d0");
a6 = MathIeeeDoubTransBase;
d0 = parm;
__asm volatile ("
jsr a6@(-0x2a)"
: "=r" (res)
: "r" (a6), "r" (d0)
: "d0", "d1", "a0", "a1");
return res;
}
double const tan (double parm)
{
register double res __asm("d0");
register void *a6 __asm ("a6");
register double d0 __asm("d0");
a6 = MathIeeeDoubTransBase;
d0 = parm;
__asm volatile ("
jsr a6@(-0x30)"
: "=r" (res)
: "r" (a6), "r" (d0)
: "d0", "d1", "a0", "a1");
return res;
}
double const sinh (double parm)
{
register double res __asm("d0");
register void *a6 __asm ("a6");
register double d0 __asm("d0");
a6 = MathIeeeDoubTransBase;
d0 = parm;
__asm volatile ("
jsr a6@(-0x3c)"
: "=r" (res)
: "r" (a6), "r" (d0)
: "d0", "d1", "a0", "a1");
return res;
}
double const cosh (double parm)
{
register double res __asm("d0");
register void *a6 __asm ("a6");
register double d0 __asm("d0");
a6 = MathIeeeDoubTransBase;
d0 = parm;
__asm volatile ("
jsr a6@(-0x42)"
: "=r" (res)
: "r" (a6), "r" (d0)
: "d0", "d1", "a0", "a1");
return res;
}
double const tanh (double parm)
{
register double res __asm("d0");
register void *a6 __asm ("a6");
register double d0 __asm("d0");
a6 = MathIeeeDoubTransBase;
d0 = parm;
__asm volatile ("
jsr a6@(-0x48)"
: "=r" (res)
: "r" (a6), "r" (d0)
: "d0", "d1", "a0", "a1");
return res;
}
double const exp (double parm)
{
register double res __asm("d0");
register void *a6 __asm ("a6");
register double d0 __asm("d0");
a6 = MathIeeeDoubTransBase;
d0 = parm;
__asm volatile ("
jsr a6@(-0x4e)"
: "=r" (res)
: "r" (a6), "r" (d0)
: "d0", "d1", "a0", "a1");
return res;
}
double const log (double parm)
{
register double res __asm("d0");
register void *a6 __asm ("a6");
register double d0 __asm("d0");
a6 = MathIeeeDoubTransBase;
d0 = parm;
__asm volatile ("
jsr a6@(-0x54)"
: "=r" (res)
: "r" (a6), "r" (d0)
: "d0", "d1", "a0", "a1");
return res;
}
double const sqrt (double parm)
{
register double res __asm("d0");
register void *a6 __asm ("a6");
register double d0 __asm("d0");
a6 = MathIeeeDoubTransBase;
d0 = parm;
__asm volatile ("
jsr a6@(-0x60)"
: "=r" (res)
: "r" (a6), "r" (d0)
: "d0", "d1", "a0", "a1");
return res;
}
double const asin (double parm)
{
register double res __asm("d0");
register void *a6 __asm ("a6");
register double d0 __asm("d0");
a6 = MathIeeeDoubTransBase;
d0 = parm;
__asm volatile ("
jsr a6@(-0x72)"
: "=r" (res)
: "r" (a6), "r" (d0)
: "d0", "d1", "a0", "a1");
return res;
}
double const acos (double parm)
{
register double res __asm("d0");
register void *a6 __asm ("a6");
register double d0 __asm("d0");
a6 = MathIeeeDoubTransBase;
d0 = parm;
__asm volatile ("
jsr a6@(-0x78)"
: "=r" (res)
: "r" (a6), "r" (d0)
: "d0", "d1", "a0", "a1");
return res;
}
double const log10 (double parm)
{
register double res __asm("d0");
register void *a6 __asm ("a6");
register double d0 __asm("d0");
a6 = MathIeeeDoubTransBase;
d0 = parm;
__asm volatile ("
jsr a6@(-0x7e)"
: "=r" (res)
: "r" (a6), "r" (d0)
: "d0", "d1", "a0", "a1");
return res;
}
double const floor (double parm)
{
register double res __asm("d0");
register void *a6 __asm ("a6");
register double d0 __asm("d0");
a6 = MathIeeeDoubBasBase;
d0 = parm;
__asm volatile ("
jsr a6@(-0x5a)"
: "=r" (res)
: "r" (a6), "r" (d0)
: "d0", "d1", "a0", "a1");
return res;
}
double const ceil (double parm)
{
register double res __asm("d0");
register void *a6 __asm ("a6");
register double d0 __asm("d0");
a6 = MathIeeeDoubBasBase;
d0 = parm;
__asm volatile ("
jsr a6@(-0x60)"
: "=r" (res)
: "r" (a6), "r" (d0)
: "d0", "d1", "a0", "a1");
return res;
}
#else /* There is a 68881 or 68882 (__HAVE_68881 is defined) */
const double sin(double x)
{
double value;
__asm ("fsin%.x %1,%0"
: "=f" (value)
: "f" (x));
return value;
}
const double cos(double x)
{
double value;
__asm ("fcos%.x %1,%0"
: "=f" (value)
: "f" (x));
return value;
}
const double tan(double x)
{
double value;
__asm ("ftan%.x %1,%0"
: "=f" (value)
: "f" (x));
return value;
}
const double asin(double x)
{
double value;
__asm ("fasin%.x %1,%0"
: "=f" (value)
: "f" (x));
return value;
}
const double acos(double x)
{
double value;
__asm ("facos%.x %1,%0"
: "=f" (value)
: "f" (x));
return value;
}
const double atan(double x)
{
double value;
__asm ("fatan%.x %1,%0"
: "=f" (value)
: "f" (x));
return value;
}
const double sinh(double x)
{
double value;
__asm ("fsinh%.x %1,%0"
: "=f" (value)
: "f" (x));
return value;
}
const double cosh(double x)
{
double value;
__asm ("fcosh%.x %1,%0"
: "=f" (value)
: "f" (x));
return value;
}
const double tanh(double x)
{
double value;
__asm ("ftanh%.x %1,%0"
: "=f" (value)
: "f" (x));
return value;
}
const double exp(double x)
{
double value;
__asm ("fetox%.x %1,%0"
: "=f" (value)
: "f" (x));
return value;
}
const double log(double x)
{
double value;
__asm ("flogn%.x %1,%0"
: "=f" (value)
: "f" (x));
return value;
}
const double log10(double x)
{
double value;
__asm ("flog10%.x %1,%0"
: "=f" (value)
: "f" (x));
return value;
}
const double sqrt(double x)
{
double value;
__asm ("fsqrt%.x %1,%0"
: "=f" (value)
: "f" (x));
return value;
}
const double ceil(double x)
{
int rounding_mode, round_up;
double value;
__asm __volatile ("fmove%.l fpcr,%0"
: "=dm" (rounding_mode)
: /* no inputs */ );
round_up = rounding_mode | 0x30;
__asm __volatile ("fmove%.l %0,fpcr"
: /* no outputs */
: "dmi" (round_up));
__asm __volatile ("fint%.x %1,%0"
: "=f" (value)
: "f" (x));
__asm __volatile ("fmove%.l %0,fpcr"
: /* no outputs */
: "dmi" (rounding_mode));
return value;
}
const double floor(double x)
{
int rounding_mode, round_down;
double value;
__asm __volatile ("fmove%.l fpcr,%0"
: "=dm" (rounding_mode)
: /* no inputs */ );
round_down = (rounding_mode & ~0x10)
| 0x20;
__asm __volatile ("fmove%.l %0,fpcr"
: /* no outputs */
: "dmi" (round_down));
__asm __volatile ("fint%.x %1,%0"
: "=f" (value)
: "f" (x));
__asm __volatile ("fmove%.l %0,fpcr"
: /* no outputs */
: "dmi" (rounding_mode));
return value;
}
#define NAN(value) __asm ("fmoved %#0rnan,%0" : "=f" (value): )
const double pow(double x, double y)
{
register double value;
if (x > 0) return exp (y * log (x));
if (x == 0)
{
if (y==0)
{
NAN(value);
return value;
}
return (0.0) ;
}
__asm ("fintrz%.x %1,%0"
: "=f" (value) /* integer-valued float */
: "f" (y));
if (y!=value)
{
NAN(value);
return value;
}
x=y*log(-x);
return ( ( ((int)y&1) == 0) ? exp(x) : -exp(x) );
}
#endif /* __HAVE_68881 */